查看原文
其他

Frida动静态结合分析Base64签名校验的四个变种

Avacci 看雪学苑 2022-07-01


看雪论坛作者ID:Avacci



1




目标app为algorithmbase_10.apk。
 
点击CHECK会有加密后的字符串,看样子是Base64编码:

 
用jadx查看源码中关键代码:
 
输出的值由MainActivity类的静态方法encodeFromJni_10生成,该方法需要传入一个16个字符的随机字符串。

encodeFromJni_10是一个native方法:

其实现应该在libnative-lib.so中:

在ida中打开so文件,查看encodeFromJni_10方法的具体实现。
 
用findcrypt脚本定位到base64编码表:

 
既然能被识别,那应该是个标准的编码表,先从logcat中得到一批参数密文对:
分别放入CyberChef中直接尝试下:
 
 
看起来就是单纯的Base64编码。
 
为了方便对更多输入值进行确认,写了个frida脚本,将encodeFromJni_10执行后的值和调用Base64.encodeToString后的值进行比较,查看是否相等。
 
多次测试后发现确实都相等,确定就是标准的Base64编码。



2




目标app为algorithmbase_11.apk.
 
打开测试后,和之前的algorithmbase_10.apk结果十分相似,也像是用Base64编码:

直接定位其so中的encodeFromJni_111方法实现.
 
用findcrypt没有找到可用信息:

但离返回值最近的方法(后面做内存回收的不算)调用中可以发现类似base64编码表的内容:


双击查看完整内容:


 
猜测应该是非标准的base64编码,使用了自定义的编码表,将编码表复制到CyberChef中(还要加上等号):
 
从logcat中取两个测试案例,验证没有问题。
 


3




目标app为algorithmbase_12.apk。
 
点击测试后发现比之前两个app结果更加杂乱:

 
还是直接查看so文件中对应native方法encodeFromJni_112的实现。发现与之前的111极为相似。而加密的关键函数内部的实现,除了使用的编码表外一模一样。


 
按理说就是使用了另一种自定义编码表的base64编码才对。但是提取出其编码表并放入CyberChef中测试,发现密文结果并不一致。

 
CyberChef的结果为:
 
Logcat获取到的实际结果为:
会不会是base64编码完后还有什么步骤?还是说传入的参数在base64编码之前有被修改呢?为了确定这点,用frida hook了做base64操作的函数,输出其执行前后参数的内容。
 

发现传入的第二个参数就是原始生成的随机字符串,而函数执行完后第一个参数中存放的内容就是最后打印出来的密文。
 

看来没有什么额外加密步骤。那唯一的变数就是编码表的内容了。会不会是运行的时候编码表被改了呢。直接用一段脚本打印运行时内存中的编码表内容。
发现果不其然和静态看的不一样。
 
将这段编码表内容放入CyberChef中,就可以得到正确的结果了:

那么编码表是何时被修改的呢?在ida中查找下编码表的引用:

 
发现有一处指向了另外一个之前没关注到的函数内部。很明显编码表就是在这里做了修改。

 这个方法也是在encodeFromJni_112方法比较前期的地方就被调用。

 
其他应该就没什么问题了。


4




目标app为algorithmbase_13.apk.

看结果又是变种base64编码的样子:

直接去观察so中native方法encodeFromJni_113用到的编码表:
 
和12用到的一样,不过测试发现用这个表得到的结果和打印出来的值不一致。猜测又是运行时被修改了。
 
先用之前的脚本确定没有其他加密过程:



再查看下运行时内存中的编码表内容:
 
将这部分内容作为编码表,到CyberChef上测试,发现提示编码表长度不对。

 
检查后发现CyberChef中的base64编码表对‘-’的位置有要求,如果单纯的放在两个字母或者数字中间会被判定为表示区间的字符。可以用’\’进行转义:

但是转完后生成的结果和目标结果不一致:
之前已经用frida hook脚本确定了所有加密只可能在函数sub_8b04中完成,那问题肯定还在这个函数中。
 
在ida中对照12和13两个apk的sub_8b04函数,发现13的sub_8b04函数中有两行代码与12不一致,多了一步异或操作。这里异或的变量v4值等于传入的第三个参数的值,也就是待编码内容的长度。

 
看来是base64编码的另一种魔改方式,这在CyberChef上应该是模拟不了了,需要自己实现一段代码。
只需要在标准的base64编码实现上,修改对应的地方即可。
 
再次运行就可以得到正确的内容了:





 


看雪ID:Avacci

https://bbs.pediy.com/user-home-879855.htm

*本文由看雪论坛 Avacci 原创,转载请注明来自看雪社区





# 往期推荐

1.Kernel从0开始

2.进程隐藏技术

3.基于模糊加权随机森林算法的恶意软件检测

4.Windows内核不触发PG Hook NtDeviceIoControlFile

5.0day书中内核漏洞exploitme.sys的学习记录

6.协议Fuzz工具整合



公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com



球分享

球点赞

球在看



点击“阅读原文”,了解更多!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存